/**
 * 多文件上传组件
 ****/
var defaultOpts = {
    timeout: 180, //超时时间 秒
    url: undefined,
    successColor:"#05DE5F",
    backgroundColor:'#505DF7',
    fileParamName: 'attachments',
    dislabel:false,//是否显示文本提示
    onlyOne:false, //只能选择上传一个文件
    dragUpload:false,
    multiple: true, //是否可批量选择
    immediate: true, //选择文件后是否立即自动上传，即不用用户点击提交按钮就上传
    accept: undefined,   // 可上传的文件类型 .xml,.xls,.xlsx,.png
    successAlert:true, //开启成功提示
    onDelected: undefined, //删除回调
    success: undefined,  //成功时候的回调  
    setParams: undefined,//设置参数 return {}
    error: undefined //错误回调
};
class Upload extends $B.BaseControl {
    constructor(elObj, opts) {
        super();
        super.setElObj(elObj);
        this.opts = $B.extendObjectFn(true, {}, defaultOpts, opts);
        $B.DomUtils.addClass(this.elObj, "k_mutilupload_wrap");
        this.cfg = $B.config.upload;
        this.label = this.opts.label ? this.opts.label : this.cfg.label;
        this.formData = new FormData();
        this.makeUi();
    }
    makeUi() {
        $B.DomUtils.css(this.elObj, {
            display: "inline-block"
        });
        this.$list = $B.DomUtils.createEl("<div></div>");
        var $btn = $B.DomUtils.createEl("<button style='background:"+this.opts.backgroundColor+"'><i class='fa fa-upload-cloud' style='padding-right:5px;color:#fff;'></i><span style='color:#fff;'>" + this.label + "</span></button>");
        if(this.opts.dislabel){
            $btn.lastChild.style.display = "none";
            $btn.firstChild.style.paddingRight = "0px";
            this.$list.style.display = "none";
        }
        if(this.opts.style){
            $B.Dom.css($btn,this.opts.style);
            if(this.opts.style["font-size"]){
                $btn.firstChild.style.fontSize = this.opts.style["font-size"];
            }
        }
        this.$uploadBtn = $btn;
        $B.DomUtils.append(this.elObj, $btn);
      
        $B.DomUtils.append(this.elObj, this.$list);
        this.$fileInput = $B.DomUtils.append(this.elObj, "<input style='display:none;' type='file' name='k_upload_file'/>");
        if (this.opts.accept) {
            $B.DomUtils.attribute(this.$fileInput, { accept: this.opts.accept });
        }
        if (this.opts.multiple) {
            $B.DomUtils.attribute(this.$fileInput, { multiple: this.opts.multiple });
        }
        $B.DomUtils.click($btn, (e) => {
            this.openBrowse();
        });
        this.accept = undefined;
        if(this.opts.accept){
            let tmpArr = this.opts.accept.toLowerCase().split(",");
            this.accept = {};
            for(let i =0 ; i< tmpArr.length ;i++){
                this.accept[tmpArr[i]] =1;
            }
        }
        $B.DomUtils.change(this.$fileInput, (e) => {  
            if(this.opts.immediate){
                if(this.$list.children && this.$list.children.length > 0){
                    this.formData.delete(this.opts.fileParamName);
                    $B.DomUtils.remove(Array.from( this.$list.children));
                }               
            }         
            let el = e.target;
            this._saveFiles(el);  
            this.$fileInput.value = "";          
        });
        if(this.opts.dragUpload){
            $B.DomUtils.addListener(this.$uploadBtn,"dragenter",(e)=>{
                return false;
            });
            $B.DomUtils.addListener(this.$uploadBtn,"dragover",(e)=>{
                return false;
            });
            $B.DomUtils.addListener(document.body,"drop",(e)=>{
                return false;
            });
            $B.DomUtils.addListener(this.$uploadBtn,"dragleave",(e)=>{
                return false;
            });
            $B.DomUtils.addListener(this.$uploadBtn,"drop",(e)=>{
                if(this.isUploading){
                    return false;
                }   
                if(this.opts.immediate){
                    if(this.$list.children && this.$list.children.length > 0){
                        this.formData.delete(this.opts.fileParamName);
                        $B.DomUtils.remove(Array.from( this.$list.children));
                    } 
                }
                var fileList = e._e.dataTransfer.files;
                if(fileList.length > 0 ){
                    this._saveFiles({files:fileList}); 
                }
                return false;
            });           
        }
        if(this.opts.onReader){
            this.opts.onReader(this.$uploadBtn);
        }
        //单个文件上传，检查右侧位置，如果宽度够，则采用一行显示
        this.isHorisionUi = false;
        if(!this.opts.multiple && this.opts.onlyOne){  
            setTimeout(()=>{
                let w = $B.DomUtils.innerWidth(this.elObj.parentNode);                 
                if(w > 299){ 
                    this.$list.style.display = "inline-block";
                    this.$list.style.paddingLeft = "14px";
                    this.isHorisionUi = true;
                }
            },1); 
        }
    }
    _saveFiles(el){       
        let files = [];
        for(let i =0 ; i < el.files.length ;i++){
            if(!this.accept || this.accept === ".*" || this.accept[".*"]){
                files.push(el.files[i]);
            }else{
                let _name = el.files[i].name;
                let idx = _name.lastIndexOf(".");
                if(idx > 0){
                    let subfix = _name.substring(idx).toLowerCase();
                    if(this.accept[subfix]){
                        files.push(el.files[i]);
                    }
                }                    
            }                
        }
        let fileName = [];
        for (let i = 0; i < files.length; i++) {                
            fileName.push(files[i].name);
        }
        let go = true, r;
        if (this.opts.onSelected) {
            if (files.length === 1) {
                r = this.opts.onSelected(fileName.join(""), files[0]);
            } else {
                r = this.opts.onSelected(fileName, files);
            }
        }
        if (typeof r !== "undefined") {
            go = r;
        }
        if (go) {
            for (let i = 0; i < files.length; i++) {
                this.formData.append(this.opts.fileParamName, files[i]);
                this.renderOneFile(files[i], i);
            } 
            if(this.opts.immediate){
                setTimeout(()=>{
                    this.upload();
                },500);                   
            }               
        } 
    }
    renderOneFile(file) {
        if(this.opts.onlyOne){
            this.clear();
        }
        let fileName = file.name;
        let paddTop = "padding-right:10px;padding-top:12px;";
        if(this.isHorisionUi){
            paddTop = "padding:0px;";
        }
        let $o = $B.DomUtils.append(this.$list, "<p style='"+paddTop+"'><span >" + fileName + "</span><i filename='" + fileName + "' title='" + this.cfg.delete + "' style='cursor:pointer;position:relative;left:3px;' class='fa fa-cancel-circled ifr_inner_delbtn'></i></p>");
        if (!this.deleteEv) {
            this.deleteEv = (e) => {
                let el = e.target;
                let filename = $B.DomUtils.attribute(el, "filename");
                let file;
                let files = this.formData.getAll(this.opts.fileParamName);
                let tmp = [];
                for (let i = 0; i < files.length; i++) {
                    if (filename !== files[i].name) {
                        tmp.push(files[i]);
                    }else{
                        file = files[i];
                    }
                }
                this.formData.delete(this.opts.fileParamName);                  
                for (let i = 0; i < tmp.length; i++) {
                    this.formData.append(this.opts.fileParamName, tmp[i]);
                }                   
                $B.DomUtils.remove(el.parentNode);            
                if(this.opts.onDelected){
                    this.opts.onDelected(filename,file);
                }                
                return false;
            };
        }
        $B.DomUtils.click($o.lastChild, this.deleteEv);
    }
    openBrowse() {
        let ie = navigator.appName == "Microsoft Internet Explorer" ? true : false;
        if (ie) {
            this.$fileInput.click();
        } else {
            let a = document.createEvent("MouseEvents");
            a.initEvent("click", true, true);
            this.$fileInput.dispatchEvent(a);
        }
    }
    upload() {
        if(this.isUploading){
            return;
        }        
        let files = this.formData.getAll(this.opts.fileParamName);
        clearTimeout(this._tempTimer);
        let $label = this.$uploadBtn.lastChild;
        if (!files || files.length === 0) {
            $label.innerText = this.cfg.emptyWarning;
            $B.DomUtils.addClass($label, "k_font_blink");
            this._tempTimer = setTimeout(() => {
                $label.innerText = this.label;
                $B.DomUtils.removeClass($label, "k_font_blink");
            }, 1100);
            return;
        }
        if (this.opts.setParams) {
            let prs = this.opts.setParams();
            if (prs) {
                for (let key in prs) {
                    this.formData.delete(key);
                    this.formData.append(key, prs[key]);
                }
            }
        }
        this.isUploading = true;
        let childs = this.$list.children;
        let color = $B.DomUtils.css(childs[0].firstChild,"color");        
        for(let i = 0; i < childs.length ;i++){
           $B.DomUtils.removeClass(childs[i].lastChild,"fa-cancel-circled fa-ok-1");
           $B.DomUtils.addClass(childs[i].lastChild,"fa-spin5 animate-spin");           
           $B.DomUtils.css(childs[i].lastChild,{color:color});
           $B.DomUtils.attribute(childs[i].lastChild,{title:this.cfg.uploading});
        }
        $label.innerText = this.cfg.uploading + "0%";
        $B.request({
            timeout:this.opts.timeout,
            url: this.opts.url,
            type: "POST",
            processData: false,
            contentType: false,
            data: this.formData,
            fail: (msg, res) => {
                this.isUploading = false;                               
                for(let i = 0; i < childs.length ;i++){
                    $B.DomUtils.addClass(childs[i].lastChild,"fa-cancel-circled");
                    $B.DomUtils.removeClass(childs[i].lastChild,"fa-spin5 animate-spin");
                    $B.DomUtils.attribute(childs[i].lastChild,{title:this.cfg.delete});
                 }                                 
                 let errMsg = msg !== null &&  msg !== '' ? msg :this.cfg.errMsg;
                 if($B.error && $B.Panel){
                    $B.error(errMsg);
                    $label.innerText = this.label ; 
                 }else{
                    $label.innerText = errMsg ; 
                    $B.DomUtils.addClass($label, "k_font_blink");
                    this._tempTimer = setTimeout(() => {
                        $label.innerText = this.label;
                        $B.DomUtils.removeClass($label, "k_font_blink");
                    }, 2500);
                 }
                 if(this.opts.error){
                    this.opts.error(msg, res);
                 } 
            },
            ok: (res, data) => {
                this.isUploading = false; 
                this.formData.delete(this.opts.fileParamName);
                for(let i = 0; i < childs.length ;i++){
                    $B.DomUtils.addClass(childs[i].lastChild,"fa-ok-1");
                    $B.DomUtils.removeClass(childs[i].lastChild,"fa-spin5 animate-spin");
                    $B.DomUtils.attribute(childs[i].lastChild,{title:this.cfg.delete + "("+this.cfg.success +")"});
                    $B.DomUtils.css(childs[i].lastChild,{color:this.opts.successColor});
                 }
                 let successMsg = res !== null &&  res !== '' ? res :this.cfg.success;
                 if(this.opts.successAlert){
                    if($B.success && $B.Panel){
                        $B.success(successMsg,1.5);
                        $label.innerText = this.label;
                    }else{
                        $label.innerText = successMsg ; 
                        $B.DomUtils.addClass($label, "k_font_blink");
                        this._tempTimer = setTimeout(() => {
                            $label.innerText = this.label;
                            $B.DomUtils.removeClass($label, "k_font_blink");
                        }, 2500);
                    }
                 }else{
                    $label.innerText = this.label ;
                 }
                 if(this.opts.success){
                    this.opts.success(res, data);
                 }
            },
            onProgress: (rate) => {    
                if(rate === 100){
                    rate = 99;
                }            
                $label.innerText = this.cfg.uploading + rate + "%";
            }
        });
    }
    hasFiles(){
        let files = this.formData.getAll(this.opts.fileParamName);
        return files.length > 0;
    }
    clear(neetTip){
        if(this.$list.children && this.$list.children.length > 0){
            this.formData.delete(this.opts.fileParamName);
            $B.DomUtils.remove(Array.from( this.$list.children));
        } 
        if(neetTip){
            if($B.message && $B.Panel){
                $B.message(this.cfg.clearLabel,1.2);
            }    
        }           
    }
}
$B["Upload"] = Upload;


/***
    * 下载封装
    * el : 提示下载的容器
    * args = {    *  
    *  url: 下载地址，
    *  message:'提示语',
    *  ivtTime:'检测间距，毫秒',
    *  params：{},附加的参数
    *  onSuccess:function(res){}
    * }
    * ***/
$B["Download"] = function(el,args){
    if(typeof el === "string"){
        el = document.getElementById(el);
    }else{
        $B.DomUtils.removeChilds(el);
    }
    var inteVal, ivtTime = args.ivtTime ? args.ivtTime :1500;
    var finish_down_key = $B.getUUID();
    var ifrId = "k_" + $B.getShortID();
    var ifr = $B.DomUtils.createEl('<iframe name="' + ifrId + '" id="' + ifrId + '" style="display: none"></iframe>');
    $B.DomUtils.append(el,ifr);
    var message = $B.config ? $B.config.exporting : "正在下载......";
    var _url = args.url;
    if (_url.indexOf("?") > 0) {
        _url = _url + "&isifr=1&_diff=" + $B.generateMixed(4);
    } else {
        _url = _url + "?isifr=1&_diff=" + $B.generateMixed(4);
    }
    var $msg = $B.DomUtils.createEl("<h3 id='k_file_export_xls_msg_'  style='height:20px;line-height:20px;text-align:center;padding-top:30px;'><div class='loading' style='width:100%;margin:0px auto;'><i class='fa-spin3 animate-spin'></i><span style='padding-left:12px;'>" + message + "</span></div></h3>");
    var $form = $B.DomUtils.createEl('<form action="' + _url + '" target="' + ifrId + '" method="post" ></form>');

    if ($B.isPlainObjectFn(args.params)) {
        Object.keys(args.params).forEach(function (p) {
            var v = args.params[p];
            $B.DomUtils.append($form,'<input type="hidden" id="' + p + '" name="' + p + '" value="' + encodeURIComponent(v) + '"/>');
        });
    }
    $B.DomUtils.append($form,'<input type="hidden" id="_down_key_" name="_down_key_" value="' + finish_down_key + '"/>');

    var callReturn = typeof args.onSuccess === 'function';
    $B.DomUtils.append(el,$msg);
    $B.DomUtils.append(el,$form);
    var onCompleteFn = ()=>{
        clearInterval(inteVal);
        try {            
            var _$body = window.frames[ifrId].document.body;
            var res = _$body.innerText;
            if (res && res !== '') {
                var json = eval("(" + res + ")");
                $msg.innerHTML = "<h2>" + json.message + "</h2>";
                if (json.code === 0) {
                    if (callReturn) {
                        args.onSuccess(json);
                    }
                }
                return;
            }
        } catch (e) {
            $msg.innerHTML =  "<h2>" +  $B.config ? $B.config.exportException : 'sorry，exception happen！'+ "</h2>";
            console.log(e);
            return;
        }
    };
    var regex = /(\/\w+)/g;
    var match, lastChar;
    do {
        match = regex.exec(args.url);
        if (match !== null) {
            lastChar = match[0];
        }
    } while (match !== null);
    var url = args.url.replace(lastChar, "/checkresponse");
    if (url.indexOf("?") > 0) {
        url = url + '&k_finish_down_key_=' + finish_down_key;
        url = url.replace("cmd=","_a=");
    } else {
        url = url + '?k_finish_down_key_=' + finish_down_key;
    }
    inteVal = setInterval(()=>{
        $B.request({
            url: url + "&_t=" + $B.generateMixed(5),
            ok: function (msg, data, res) {
                if (msg !== 'null' && msg !="") {
                    clearInterval(inteVal);
                    $msg.innerHTML = "<h2>" + msg + "</h2>";
                    if (callReturn) {
                        setTimeout(function () {
                            args.onSuccess(res);
                        }, 1500);
                    }
                }
            },
            fail:function(){},
            error:function(){}
        });
    },1000);
    $B.DomUtils.onload(ifr,onCompleteFn);
    $form.submit();
};